package com.wskj.pay.impl;


import com.alipay.api.AlipayClient;
import com.alipay.api.CertAlipayRequest;
import com.alipay.api.DefaultAlipayClient;
import com.alipay.api.domain.AlipayTradeRefundModel;
import com.alipay.api.request.AlipayTradeRefundRequest;
import com.alipay.api.response.AlipayTradeRefundResponse;
import com.github.wxpay.sdk.WXPay;
import com.github.wxpay.sdk.WXPayConstants;
import com.github.wxpay.sdk.WXPayUtil;
import com.wskj.common.utils.common.AssertUtils;
import com.wskj.common.utils.wx.WXConfigUtil;
import com.wskj.config.properties.AliPayConstants;
import com.wskj.pay.IPayService;
import com.wskj.system.domain.SysCommon;
import com.wskj.system.service.ISysCommonService;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.util.HashMap;
import java.util.Map;

/**
 * @author fang
 * @date 2020/2/26
 */
@Slf4j
@AllArgsConstructor
@Service
public class PayServiceImpl implements IPayService {

    private final ISysCommonService iSysCommonService;
    @Override
    public Boolean wxRefund(String outTradeNo,String inTradeNo,String outRefundNo, BigDecimal moneys) {
        WXConfigUtil config = null;
        try {
            config = new WXConfigUtil();
        } catch (Exception e) {
            e.printStackTrace();
        }
        Long commInfoId = 0L;
        // 1 app微信 2微信公众号 3 微信小程序 todo
        Integer payWay = 1;
        switch (payWay) {
            case 1:
                // appId
                commInfoId = 1000004L;
                break;
            case 2:
                // 公众号id
                commInfoId = 1000055L;
                break;
            case 3:
                // 小程序id
                commInfoId = 1000002L;
                break;
        }
        config.setAppId(iSysCommonService.getById(commInfoId).getCommonValue());
        // 微信商户key
        config.setKey(iSysCommonService.getById(1000006L).getCommonValue());
        // 微信商户号mchId
        config.setMchId(iSysCommonService.getById(1000007L).getCommonValue());
        WXPay wxpay = new WXPay(config);
        try {
            Map<String, String> data = new HashMap<>();
            data.put("appid", config.getAppID());
            data.put("mch_id", config.getMchID());
            data.put("nonce_str", WXPayUtil.generateNonceStr());
            data.put("sign", WXPayUtil.generateSignature(data, config.getKey(), WXPayConstants.SignType.MD5));
            // 订单号,支付单号一致
            data.put("out_trade_no", outTradeNo);
            // 三方交易号
            data.put("transaction_id",inTradeNo);
            // 退款单号，同一笔用不同的退款单号
            data.put("out_refund_no", outRefundNo);
            BigDecimal multiply = moneys.multiply(BigDecimal.valueOf(100));
            String fee = String.valueOf(multiply.intValue());
            // 1块等于微信支付传入100); 支付总额
            data.put("total_fee", fee);
            // 1块等于微信支付传入100); 退款总额
            data.put("refund_fee", fee);
            // 使用官方API退款
            Map<String, String> response = wxpay.refund(data);
            // result_code -> FAIL
            if ("SUCCESS".equals(response.get("return_code")) && !"FAIL".equals(response.get("result_code"))) {
                // 主要返回以下5个参数
                System.out.println("微信退款成功");
                log.info("微信退款成功");
                return Boolean.TRUE;
            } else {
                return Boolean.FALSE;
            }
        } catch (Exception e) {
            log.info("微信退款异常：" + e.getMessage(), e);
            e.printStackTrace();
            return Boolean.FALSE;
        }
    }

    @Override
    public Boolean aliRefund(String outTradeNo,String inTradeNo, String outRefundNo,BigDecimal moneys) {
        SysCommon dbSysCommon = iSysCommonService.getById(1000015L);
        AlipayClient alipayClient = null;
        try{
            if("1".equals(dbSysCommon.getCommonValue())){
                // 证书模式
                //构造client
                CertAlipayRequest certAlipayRequest = new CertAlipayRequest();
                //设置网关地址
                certAlipayRequest.setServerUrl("https://openapi.alipay.com/gateway.do");
                //设置应用Id
                certAlipayRequest.setAppId(iSysCommonService.getById(1000009L).getCommonValue());
                //设置应用私钥
                certAlipayRequest.setPrivateKey(iSysCommonService.getById(1000010L).getCommonValue());
                //设置请求格式，固定值json
                certAlipayRequest.setFormat("json");
                //设置字符集
                certAlipayRequest.setCharset(AliPayConstants.CHARSET);
                //设置签名类型
                certAlipayRequest.setSignType(AliPayConstants.SIGNTYPE);
                SysCommon urls = iSysCommonService.getById(1000016L);
                certAlipayRequest.setCertPath(urls.getCommonValue() + "/appCertPublicKey_"+iSysCommonService.getById(1000009L).getCommonValue()+".crt"); //应用公钥证书路径（app_cert_path 文件绝对路径）
                certAlipayRequest.setAlipayPublicCertPath(urls.getCommonValue() + "/alipayCertPublicKey_RSA2.crt"); //支付宝公钥证书文件路径（alipay_cert_path 文件绝对路径）
                certAlipayRequest.setRootCertPath(urls.getCommonValue() + "/alipayRootCert.crt");  //支付宝CA根证书文件路径（alipay_root_cert_path 文件绝对路径）
                //构造client
                alipayClient = new DefaultAlipayClient(certAlipayRequest);
            }else{
                // 密钥模式
                alipayClient = new DefaultAlipayClient("https://openapi.alipay.com/gateway.do", iSysCommonService.getById(63).getCommonValue(), iSysCommonService.getById(65).getCommonValue(), "json", AliPayConstants.CHARSET, iSysCommonService.getById(64).getCommonValue(), "RSA2");
            }
            AlipayTradeRefundRequest alipay_request = new AlipayTradeRefundRequest();
            AlipayTradeRefundModel model = new AlipayTradeRefundModel();
            model.setOutTradeNo(outTradeNo);//订单编号
            model.setTradeNo(inTradeNo);//支付宝订单交易号
            model.setRefundAmount(moneys.toString());//退款金额 不得大于订单金额
            model.setRefundReason("服务退款");//退款说明
            model.setOutRequestNo(outRefundNo);//标识一次退款请求，同一笔交易多次退款需要保证唯一，如需部分退款，则此参数必传。
            alipay_request.setBizModel(model);
            AlipayTradeRefundResponse alipay_response = alipayClient.certificateExecute(alipay_request);
            AssertUtils.isFalse("40004".equals(alipay_response.getCode()),"支付宝平台余额不足");
            AssertUtils.isFalse("40000".equals(alipay_response.getCode()),"支付宝交易已经关闭");
            String alipayRefundStr = alipay_response.getBody();
            log.info(alipayRefundStr);
            return Boolean.TRUE;
        }catch(Exception e){
            e.printStackTrace();
            log.error("支付宝退款异常:"+e.getMessage());
            AssertUtils.isFalse(Boolean.TRUE,e.getMessage());
        }
        return Boolean.FALSE;
    }
}